﻿using System.IO;
using System.Security.Cryptography;

namespace Apewer.Internals
{

    class DesHelper
    {

        private static byte[] Fill(byte[] argbytes)
        {
            const int MaxLength = 8;
            var vresult = new byte[MaxLength];
            if ((argbytes == null) || (argbytes.Length == 0))
            {
                for (int i = 0; i < MaxLength; i++) vresult[i] = 0;
                return vresult;
            }
            else
            {
                var vrl = 0;
                while (true)
                {
                    for (int i = 0; i < argbytes.Length; i++)
                    {
                        if (vrl >= MaxLength) return vresult;
                        vresult[vrl] = argbytes[i];
                        vrl += 1;
                    }
                }
            }
        }

        private static DESCryptoServiceProvider Provider(byte[] argkey, byte[] argvector)
        {
            var vkey = Fill(argkey);
            var viv = Fill(argvector);

            var vcsp = new DESCryptoServiceProvider();
            vcsp.Key = vkey;
            vcsp.IV = viv;
            return vcsp;
        }

        /// <summary>对数据进行 DES 加密。</summary>
        private static byte[] Encrypt(byte[] argdata, byte[] argkey, byte[] argvector)
        {
            if ((argdata == null) || (argdata.Length == 0)) return argdata;
            var vresult = Constant.EmptyBytes;

            var vms = new MemoryStream();
            var vcs = new CryptoStream(vms, Provider(argkey, argvector).CreateEncryptor(), CryptoStreamMode.Write);
            //try
            {
                vcs.Write(argdata, 0, argdata.Length);
                vcs.FlushFinalBlock();
                vresult = vms.ToArray();
            }
            //finally { }
            vcs.Dispose();
            vms.Dispose();

            return vresult;
        }

        /// <summary>对数据进行 DES 解密。</summary>
        private static byte[] Decrypt(byte[] argdata, byte[] argkey, byte[] argvector)
        {
            if ((argdata == null) || (argdata.Length == 0)) return argdata;
            var vresult =Constant. EmptyBytes;

            var vms = new MemoryStream();
            var vcs = new CryptoStream(vms, Provider(argkey, argvector).CreateDecryptor(), CryptoStreamMode.Write);
            //try
            {
                vcs.Write(argdata, 0, argdata.Length);
                vcs.FlushFinalBlock();
                vresult = vms.ToArray();
            }
            //finally { }
            vcs.Dispose();
            vms.Dispose();

            return vresult;
        }

    }

}
